/*
 * $Id: $
 * 
 * Copyright (c) 2001-2008 Accentrix Company Limited. All Rights Reserved.
 * 
 * Accentrix Company Limited. ("Accentrix") retains copyright on all text, source
 * and binary code contained in this software and documentation. Accentrix grants
 * Licensee a limited license to use this software, provided that this copyright
 * notice and license appear on all copies of the software. The software source
 * code is provided for reference purposes only and may not be copied, modified 
 * or distributed.
 * 
 * THIS SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS," WITHOUT ANY WARRANTY OF
 * ANY KIND UNLESS A SEPARATE WARRANTIES IS PURCHASED FROM ACCENTRIX AND REMAINS
 * VALID.  ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 * PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ACCENTRIX SHALL NOT BE LIABLE
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING OR MODIFYING THE
 * SOFTWARE OR ITS DERIVATIVES.
 * 
 * IN NO EVENT WILL ACCENTRIX BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
 * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES,
 * HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE
 * USE OF OR INABILITY TO USE SOFTWARE, EVEN IF ACCENTRIX HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */
package com.lightsaber.trade.cloth.service.planning;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.lightsaber.trade.cloth.dao.planning.Level1PlanningDao;
import com.lightsaber.trade.cloth.entity.category.Category;
import com.lightsaber.trade.cloth.entity.category.CategoryNode;
import com.lightsaber.trade.cloth.entity.planning.Level1Planning;
import com.lightsaber.trade.cloth.entity.planning.Planning;
import com.lightsaber.trade.cloth.entity.planning.PlanningStatus;

@Service
@Transactional
public class FirstLevelEndorseManager {
    private final static Logger log = LoggerFactory.getLogger(FirstLevelEndorseManager.class);

    @Autowired
    private PlanningService planningService;
    @Autowired
    private Level1PlanningDao level1PlanningDao;

    public String generateSelectionTree(final String planningId,
            final Map<String, String> endorseMap) {
        StringBuffer gridDoc = new StringBuffer();
        gridDoc.append("<Grid><Cfg id='SelectionGrid' MainCol='A' ColMoving='0' Dragging='0' Sorting='0' Alternate='0'/>");

        Planning planning = planningService.get(planningId);

        Category category = planning.getCategory();

        // 1. Add columns to Grid
        generateCols(gridDoc);

        // 2. Add Head to Grid
        generateHead(gridDoc, category);

        // 3. Add body to Grid
        generateBody(gridDoc, category, endorseMap);

        gridDoc.append("<Toolbar Visible='0'/>");
        gridDoc.append("<Panel Copy='0' Move='0' Select='0' Delete='0'/></Grid>");
        return gridDoc.toString();
    }

    private void generateBody(final StringBuffer gridDoc, final Category category,
            final Map<String, String> endorseMap) {
        StringBuffer sb = new StringBuffer();

        sb.append("<Body><B>");

        recursionTree(sb, category.getRoot(), endorseMap);

        sb.append("</B></Body>");

        log.debug("body ={}", sb.toString());
        gridDoc.append(sb.toString());
    }

    private void recursionTree(final StringBuffer sb, final CategoryNode node,
            final Map<String, String> endorseMap) {

        // Grid's Leaf
        if (node.getOwnedBranchTrees().size() > 0) {
            sb.append("  <I id='"
                    + node.getId()
                    + "' Def='Tree' A='"
                    + node.getName()
                    + "' "
                    + "DButton=\"&lt;input type='button' class='dButton' onclick='toView(&quot;svsh&quot;)' value='View' /&gt;\" "
                    + "CDefaults='");

            List<Category> cgList = node.getOwnedBranchTrees();

            // 1. when endorseMap is null, the Planning is endorsed
            if (endorseMap == null) {
                Level1Planning level1Planning = null;

                for (Category branchTree : cgList) {
                    level1Planning = level1PlanningDao.findByBranchTree(branchTree);

                    if (level1Planning.getStatus() == PlanningStatus.Endorsed) {
                        sb.append("|" + level1Planning.getName());

                        sb.append("' C='" + level1Planning.getName()
                                + "' RStatus='Endorsed' > </I>");
                        break;
                    }
                }

                return;
            }

            // 2. when endorseMap is not null, the Planning is not endorsed
            String firstName = "";
            for (int i = 0; i < cgList.size(); i++) {

                Level1Planning level1Planning = level1PlanningDao.findByBranchTree(cgList.get(i));

                if (level1Planning.getStatus() == PlanningStatus.WaitingForEndorsement) {

                    if (StringUtils.isBlank(firstName)) {
                        firstName = level1Planning.getName();
                    }

                    sb.append("|" + level1Planning.getName());
                }
            }

            String planNameInSession = endorseMap.get(node.getId());
            if (planNameInSession == null || planNameInSession == "") {
                sb.append("' C='" + firstName + "' RStatus='Waiting For Endorsement' > </I>");
                endorseMap.put(node.getId(), firstName);

            } else {
                sb.append("' C='" + planNameInSession
                        + "' RStatus='Waiting For Endorsement' > </I>");
            }

            return;
        }

        if (node.getChildren().size() <= 0) {
            sb.append("<I Def='Leaf' A='" + node.getName() + "' CButton='None' ></I>");
            return;
        }

        // Grid's Tree
        sb.append("<I Def='Tree' A='" + node.getName() + "' CButton='None' >");
        for (CategoryNode child : node.getChildren()) {
            recursionTree(sb, child, endorseMap);
        }

        sb.append("</I>");

    }

    private void generateHead(final StringBuffer gridDoc, final Category category) {
        StringBuffer sb = new StringBuffer();

        sb.append("<Head>");
        sb.append("<Header Spanned='1' ASpan='4' A='Planning Exercise : "
                + category.getPlanningExerciseName() + "' AType='Html'/>");

        sb.append("<Header id='Header'  A='Programme' AAlign='Left' AType='Html' "
                + "C='Available Planning' CAlign='Center' CType='Html'  "
                + "DButton='Remark' DButtonAlign='Center' DButtonType='Html' "
                + "RStatus='Status' RStatusAlign='Center' RStatusType='Html' />");

        sb.append("</Head>");

        log.debug("Head ={}", sb.toString());
        gridDoc.append(sb.toString());
    }

    private void generateCols(final StringBuffer gridDoc) {
        StringBuffer sb = new StringBuffer();

        sb.append("<Cols>");
        sb.append("<C Name='A' Width='300' CanEdit='0' />");

        sb.append("<C Name='C' Width='150' CanEdit='0' Align='Center' Button='Defaults' />");
        sb.append("<C Name='DButton' Width='100' CanEdit='0' Align='Center' Type='Html' />");
        sb.append("<C Name='RStatus' Width='100' CanEdit='0' Align='Center' Type='Html' />");

        sb.append("</Cols>");

        log.debug("Cols ={}", sb.toString());
        gridDoc.append(sb.toString());
    }

}
